---
title: 'MCP'
sidebarTitle: 'MCP'
description: 'How to use the built-in MCP server from Nango'
---

## How the server works

MCP servers expose your Nango actions as tools that can be invoked by LLM clients. Nango [actions](/guides/use-cases/actions) are predefined API interactions that you can run through Nango. For example, creating a calendar event in Google Calendar or fetching recent leads from a CRM. These are the operations exposed to the LLM via the MCP server.

When an LLM client connects to your MCP server:

1. The server authenticates the request using your Nango secret key
2. It identifies available actions based on the provided connection ID and integration ID (a.k.a. provider config key)
3. It exposes these actions as tools for the LLM to invoke
4. When the LLM invokes a tool, the MCP server executes the corresponding Nango action

## Authentication

Requests to the MCP server must include the following headers:

- `Authorization`: Bearer token with your Nango secret key
- `connection-id`: The connection ID that determines available actions
- `provider-config-key`: The integration ID

## Connecting to the Nango MCP server

The Nango MCP server is exposed at `https://api.nango.dev/mcp` and supports the [Streamable HTTP transport](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http). The **HTTP+SSE** transport is **NOT** supported, as it's being deprecated.

### Programmatically with the Vercel AI SDK

Here's an example of connecting to the Nango MCP server using [Vercel's AI SDK](https://ai-sdk.dev/docs/introduction):
```typescript
import { openai } from "@ai-sdk/openai";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { experimental_createMCPClient, generateText } from "ai";

const mcpClient = await experimental_createMCPClient({
  transport: new StreamableHTTPClientTransport(new URL('https://api.nango.dev/mcp'), {
    requestInit: {
      headers: {
        'Authorization': 'Bearer <secret-key>',
        'connection-id': '<connection-id>',
        'provider-config-key': '<provider-config-key>'
      }
    },
  }),
});

const { text, toolCalls } = await generateText({
  model: openai('gpt-4o-mini'),
  tools: await mcpClient.tools(), // You can add tools from multiple connections
  maxSteps: 5,
  messages: [
    {
      role: 'user',
      content: 'Schedule a meeting with John Doe',
    },
  ],
});
```

Check out a full chat loop example in our [Nango MCP Client Example repo](https://github.com/NangoHQ/nango-mcp-client-example).

### Claude for Desktop

A good way to manually test the MCP server is to use [Claude Desktop](https://claude.ai/download) paired with the [mcp-remote](https://www.npmjs.com/package/mcp-remote) npm package.

Claude Desktop originally only supports the [stdio](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports#stdio) transport, but the `mcp-remote` package allows you to proxy requests to the MCP server over the Streamable HTTP transport.

1. Install [Claude Desktop](https://claude.ai/download)
2. Open `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%/Claude/claude_desktop_config.json` (Windows) in a code editor and add your desired MCP server connections using [mcp-remote](https://www.npmjs.com/package/mcp-remote). For example:
    ```json
    {
      "mcpServers": {
        "nango-google-drive": {
          "command": "npx",
          "args": [
            "-y",
            "mcp-remote",
            "https://api.nango.dev/mcp",
            "--header",
            "Authorization:Bearer <secret-key>",
            "--header",
            "provider-config-key:google-drive",
            "--header",
            "connection-id:<connection-id>"
          ]
        },
        "nango-slack": {
          "command": "npx",
          "args": [
            "-y",
            "mcp-remote",
            "https://api.nango.dev/mcp",
            "--header",
            "Authorization:Bearer <secret-key>",
            "--header",
            "provider-config-key:slack",
            "--header",
            "connection-id:<connection-id>"
          ]
        }
      }
    }
    ```
    Avoid modifying the spacing on the headers as `mcp-remote` is sensitive to it.
    
3. Restart Claude Desktop to apply the changes
4. Claude should now be able to list and execute actions from the connections you added to the config file

<Tip>
**Questions, problems, feedback?** Please reach out in the [Slack community](https://nango.dev/slack).
</Tip> 